package com.angel.flowable.service.impl;


import cn.hutool.core.util.StrUtil;
import com.angel.flowable.domain.FlowableForm;
import com.angel.flowable.service.FlowableFormService;
import com.angel.mongodb.core.BaseMongoDAO;
import com.angel.mongodb.entity.Page;
import com.angel.mongodb.entity.SortBuilder;
import com.angel.mongodb.utils.CriteriaWrapper;
import com.angel.mongodb.utils.MongoUtils;
import com.angel.mongodb.utils.Wraps;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.reflect.SerializableFunction;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 流程Service
 *
 * @author kubilewang
 */
@Service
public class FlowableFormServiceImpl implements FlowableFormService {

    @Autowired
    private BaseMongoDAO baseMongoDAO;

    public void cleanData(Class<?> clazz) {
        baseMongoDAO.getMongoTemplate().dropCollection(clazz);
    }

    public void checkRoleAllowed(SysRole role) {
        if (StringUtils.isNotNull(role.getId()) && role.isAdmin()) {
            throw new CustomException("不允许操作超级管理员角色");
        }
    }

    @Transactional(rollbackFor = Throwable.class)
    public int updateRole(SysRole role) {
        // 修改角色信息
        updateById(role);
        // 删除角色与菜单关联
        return 1;
    }

    @Transactional(rollbackFor = Throwable.class)
    public int authDataScope(SysRole role) {
        // 修改角色信息
        updateRole(role);
        return 1;
    }

    /**
     * 插入
     *
     * @param object 对象
     */
    public int save(Object object) {
        String id = (String) MongoUtils.getFieldValue(object, "id");
        Object objectOrg = StrUtil.isNotEmpty(id) ? baseMongoDAO.getMongoTemplate().findById(id, object.getClass()) : null;
        if (objectOrg != null) {
            // 数据库里已有相同id, 去除id以便插入
            MongoUtils.setFieldValue(object, "id", null);
        }

        baseMongoDAO.saveOrUpdate(object);
        id = (String) MongoUtils.getFieldValue(object, "id");
        if (id != null) {
            return 1;
        }
        return 0;
    }

    /**
     * 根据id更新
     *
     * @param object 对象
     */
    public void updateById(Object object) {
        if (StrUtil.isEmpty((String) MongoUtils.getFieldValue(object, "id"))) {
            return;
        }
        baseMongoDAO.saveOrUpdate(object);
    }

    /**
     * 根据id删除
     *
     * @param id    对象
     * @param clazz 类
     */
    public Long deleteById(String id, Class<?> clazz) {

        if (StrUtil.isEmpty(id)) {
            return 0L;
        }
        return deleteByQuery(Criteria.where("id").is(id), clazz);
    }

    /**
     * 根据id删除
     *
     * @param ids   对象
     * @param clazz 类
     */
    public Long deleteByIds(List<String> ids, Class<?> clazz) {

        if (ids == null || ids.size() == 0) {
            return 0L;
        }

        return deleteByQuery(Criteria.where("id").in(ids), clazz);
    }

    /**
     * 根据条件删除
     *
     * @param criteria 查询
     * @param clazz    类
     */
    public Long deleteByQuery(Criteria criteria, Class<?> clazz) {
        return baseMongoDAO.deleteByQuery(new Query(criteria), clazz);
    }

    /**
     * 根据条件删除
     *
     * @param criteriaWrapper 查询
     * @param clazz           类
     */
    public Long deleteByQuery(CriteriaWrapper criteriaWrapper, Class<?> clazz) {
        return baseMongoDAO.deleteByQuery(new Query(criteriaWrapper.build()), clazz);
    }

    /**
     * 更新查到的第一项
     *
     * @param criteria 查询
     * @param update   更新
     * @param clazz    类
     */
    public void updateFirst(Criteria criteria, Update update, Class<?> clazz) {
        baseMongoDAO.updateFirst(new Query(criteria), update, clazz);
    }

    /**
     * 更新查到的第一项
     *
     * @param criteriaWrapper 查询
     * @param update          更新
     * @param clazz           类
     */

    public void updateFirst(CriteriaWrapper criteriaWrapper, Update update, Class<?> clazz) {
        baseMongoDAO.updateFirst(new Query(criteriaWrapper.build()), update, clazz);
    }

    /**
     * 累加某一个字段的数量,原子操作
     *
     * @param id
     * @param property
     * @param count
     * @param clazz
     */

    public void addCountById(String id, String property, Number count, Class<?> clazz) {
        Update update = new Update().inc(property, count);
        baseMongoDAO.updateFirst(new Query(Criteria.where("id").is(id)), update, clazz);
    }

    /**
     * 累加某一个字段的数量,原子操作
     *
     * @param id
     * @param property
     * @param count
     * @param clazz
     */

    public <T, R> void addCountById(String id, SerializableFunction<T, R> property, Number count, Class<?> clazz) {
        addCountById(id, MongoUtils.getFieldName(property), count, clazz);
    }

    /**
     * 更新查到的全部项
     *
     * @param criteria 查询
     * @param update   更新
     * @param clazz    类
     */

    public void updateMulti(Criteria criteria, Update update, Class<?> clazz) {
        baseMongoDAO.updateMulti(new Query(criteria), update, clazz);
    }

    /**
     * 更新查到的全部项
     *
     * @param criteriaWrapper 查询
     * @param update          更新
     * @param clazz           类
     */

    public void updateMulti(CriteriaWrapper criteriaWrapper, Update update, Class<?> clazz) {
        baseMongoDAO.updateMulti(new Query(criteriaWrapper.build()), update, clazz);
    }

    /**
     * 按查询条件获取Page
     *
     * @param criteria 查询
     * @param page     分页
     * @param clazz    类
     * @return Page 分页
     */
    public <T> List<T> findPage(Criteria criteria, Page page, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(buildPageQuery(new Query(criteria), page), clazz);
    }

    /**
     * 按查询条件获取Page
     *
     * @param criteriaWrapper 查询
     * @param page            分页
     * @param clazz           类
     * @return Page 分页
     */
    public <T> List<T> findPage(CriteriaWrapper criteriaWrapper, Page page, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(buildPageQuery(new Query(criteriaWrapper.build()), page), clazz);
    }

    /**
     * 按查询条件获取Page
     *
     * @param criteria 查询
     * @param sort     排序
     * @param clazz    类
     * @return Page 分页
     */
    public <T> List<T> findPage(Criteria criteria, Sort sort, Page page, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(buildPageQuery(new Query(criteria).with(sort), page), clazz);
    }

    /**
     * 按查询条件获取Page
     *
     * @param criteria    查询
     * @param sortBuilder 排序
     * @param clazz       类
     * @return Page 分页
     */
    public <T> List<T> findPage(Criteria criteria, SortBuilder sortBuilder, Page page, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(buildPageQuery(new Query(criteria).with(sortBuilder.toSort()), page), clazz);
    }

    /**
     * 按查询条件获取Page
     *
     * @param criteriaWrapper 查询
     * @param sortBuilder     排序
     * @param clazz           类
     * @return Page 分页
     */
    public <T> List<T> findPage(CriteriaWrapper criteriaWrapper, SortBuilder sortBuilder, Page page, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(buildPageQuery(new Query(criteriaWrapper.build()).with(sortBuilder.toSort()), page), clazz);
    }

    /**
     * 按查询条件获取Page
     *
     * @param criteriaWrapper 查询
     * @param sort            排序
     * @param clazz           类
     * @return Page 分页
     */
    public <T> List<T> findPage(CriteriaWrapper criteriaWrapper, Sort sort, Page page, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(buildPageQuery(new Query(criteriaWrapper.build()).with(sort), page), clazz);
    }

    /**
     * 按查询条件获取Page
     *
     * @param page  分页
     * @param sort  排序
     * @param clazz 类
     * @return Page 分页
     */
    public <T> List<T> findPage(Sort sort, Page page, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(buildPageQuery(new Query().with(sort), page), clazz);
    }

    /**
     * 按查询条件获取Page
     *
     * @param sortBuilder 查询
     * @param page        排序
     * @param clazz       类
     * @return Page 分页
     */
    public <T> List<T> findPage(SortBuilder sortBuilder, Page page, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(buildPageQuery(new Query().with(sortBuilder.toSort()), page), clazz);
    }

    /**
     * 获取Page
     *
     * @param query 分页
     * @param clazz 类
     * @return Page 分页
     */
    public <T> List<T> findPage(Query query, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(query, clazz);
    }

    /**
     * 根据条件查找单个
     *
     * @param <T>      类型
     * @param criteria
     * @param clazz    类
     * @return T 对象
     */

    public <T> T findOneByQuery(Criteria criteria, Class<T> clazz) {
        return (T) baseMongoDAO.findOneByQuery(new Query(criteria), clazz);
    }

    /**
     * 根据条件查找单个
     *
     * @param criteriaWrapper
     * @param clazz           类
     * @return T 对象
     */

    public <T> T findOneByQuery(CriteriaWrapper criteriaWrapper, Class<T> clazz) {
        return (T) baseMongoDAO.findOneByQuery(new Query(criteriaWrapper.build()), clazz);
    }

    /**
     * 根据条件查找单个
     *
     * @param criteria 查询
     * @param sort     查询
     * @param clazz    类
     * @return T 对象
     */
    public <T> T findOneByQuery(Criteria criteria, Sort sort, Class<T> clazz) {
        return (T) baseMongoDAO.findOneByQuery(new Query(criteria).with(sort), clazz);
    }

    /**
     * 根据条件查找单个
     *
     * @param criteria    查询
     * @param sortBuilder 查询
     * @param clazz       类
     * @return T 对象
     */
    public <T> T findOneByQuery(Criteria criteria, SortBuilder sortBuilder, Class<T> clazz) {
        return (T) baseMongoDAO.findOneByQuery(new Query(criteria).with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据条件查找单个
     *
     * @param criteriaWrapper 查询
     * @param sort            查询
     * @param clazz           类
     * @return T 对象
     */
    public <T> T findOneByQuery(CriteriaWrapper criteriaWrapper, Sort sort, Class<T> clazz) {
        return (T) baseMongoDAO.findOneByQuery(new Query(criteriaWrapper.build()).with(sort), clazz);
    }

    /**
     * 根据条件查找单个
     *
     * @param criteriaWrapper 查询
     * @param sortBuilder     查询
     * @param clazz           类
     * @return T 对象
     */
    public <T> T findOneByQuery(CriteriaWrapper criteriaWrapper, SortBuilder sortBuilder, Class<T> clazz) {
        return (T) baseMongoDAO.findOneByQuery(new Query(criteriaWrapper.build()).with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据条件查找单个
     *
     * @param sort  查询
     * @param clazz 类
     * @return T 对象
     */
    public <T> T findOneByQuery(Sort sort, Class<T> clazz) {
        return (T) baseMongoDAO.findOneByQuery(new Query().with(sort), clazz);
    }

    /**
     * 根据条件查找单个
     *
     * @param sortBuilder 查询
     * @param clazz       类
     * @return T 对象
     */
    public <T> T findOneByQuery(SortBuilder sortBuilder, Class<T> clazz) {
        return (T) baseMongoDAO.findOneByQuery(new Query().with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据条件查找List
     *
     * @param <T>      类型
     * @param criteria 查询
     * @param clazz    类
     * @return List 列表
     */
    public <T> List<T> findListByQuery(Criteria criteria, Class<T> clazz) {
        return (List<T>) baseMongoDAO.findListByQuery(new Query(criteria), clazz);
    }

    /**
     * 根据条件查找List
     *
     * @param <T>   类型
     * @param query 查询
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findListByQuery(Query query, Class<T> clazz) {
        return (List<T>) baseMongoDAO.findListByQuery(query, clazz);
    }

    /**
     * 根据条件查找List
     *
     * @param <T>             类型
     * @param criteriaWrapper 查询
     * @param clazz           类
     * @return List 列表
     */
    public <T> List<T> findListByQuery(CriteriaWrapper criteriaWrapper, Class<T> clazz) {
        return (List<T>) baseMongoDAO.findListByQuery(new Query(criteriaWrapper.build()), clazz);
    }

    /**
     * 根据条件查找List
     *
     * @param <T>         类型
     * @param criteria    查询
     * @param sortBuilder 排序
     * @param clazz       类
     * @return List 列表
     */
    public <T> List<T> findListByQuery(Criteria criteria, SortBuilder sortBuilder, Class<T> clazz) {
        return (List<T>) baseMongoDAO.findListByQuery(new Query(criteria).with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据条件查找List
     *
     * @param <T>      类型
     * @param criteria 查询
     * @param sort     排序
     * @param clazz    类
     * @return List 列表
     */
    public <T> List<T> findListByQuery(Criteria criteria, Sort sort, Class<T> clazz) {
        return (List<T>) baseMongoDAO.findListByQuery(new Query(criteria).with(sort), clazz);
    }

    /**
     * 根据条件查找List
     *
     * @param <T>             类型
     * @param criteriaWrapper 查询
     * @param sortBuilder     排序
     * @param clazz           类
     * @return List 列表
     */
    public <T> List<T> findListByQuery(CriteriaWrapper criteriaWrapper, SortBuilder sortBuilder, Class<T> clazz) {
        return (List<T>) baseMongoDAO.findListByQuery(new Query(criteriaWrapper.build()).with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据条件查找List
     *
     * @param <T>             类型
     * @param criteriaWrapper 查询
     * @param sort            排序
     * @param clazz           类
     * @return List 列表
     */
    public <T> List<T> findListByQuery(CriteriaWrapper criteriaWrapper, Sort sort, Class<T> clazz) {
        return (List<T>) baseMongoDAO.findListByQuery(new Query(criteriaWrapper.build()).with(sort), clazz);
    }

    /**
     * 根据条件查找某个属性
     *
     * @param <T>           类型
     * @param query         查询
     * @param documentClass 类
     * @param property      属性
     * @param propertyClass 属性类
     * @return List 列表
     */
    public <T> List<T> findPropertiesByQuery(Query query, Class<?> documentClass, String property, Class<T> propertyClass) {
        query.fields().include(property);
        List<?> list = findListByQuery(query, documentClass);
        List<T> propertyList = extractProperty(list, property, propertyClass);

        return propertyList;
    }

    /**
     * 根据条件查找某个属性
     *
     * @param <T>           类型
     * @param query         查询
     * @param documentClass 类
     * @param property      属性
     * @param propertyClass 属性类
     * @return List 列表
     */
    public <T, R> List<T> findPropertiesByQuery(Query query, Class<?> documentClass, SerializableFunction<T, R> property, Class<T> propertyClass) {
        return findPropertiesByQuery(query, documentClass, MongoUtils.getFieldName(property), propertyClass);
    }

    /**
     * @param query
     * @param documentClass
     * @param property
     * @description: 根据条件查找某个属性
     * @return: java.util.List<java.lang.String>
     * @author: gankench@gmail.com
     * @time: 4/6/21 3:28 PM
     */
    public List<String> findPropertiesByQuery(Query query, Class<?> documentClass, String property) {
        return (List<String>) findPropertiesByQuery(query, documentClass, property, String.class);
    }

    /**
     * @param query
     * @param documentClass
     * @param property
     * @description: 根据条件查找某个属性
     * @return: java.util.List<java.lang.String>
     * @author: gankench@gmail.com
     * @time: 4/6/21 3:28 PM
     */
    public <T, R> List<String> findPropertiesByQuery(Query query, Class<?> documentClass, SerializableFunction<T, R> property) {
        return (List<String>) findPropertiesByQuery(query, documentClass, MongoUtils.getFieldName(property), String.class);
    }

    /**
     * 根据条件查找某个属性
     *
     * @param <T>           类型
     * @param criteria      查询
     * @param documentClass 类
     * @param property      属性
     * @param propertyClass 属性类
     * @return List 列表
     */
    public <T> List<T> findPropertiesByQuery(Criteria criteria, Class<?> documentClass, String property, Class<T> propertyClass) {
        return (List<T>) findPropertiesByQuery(new Query(criteria), documentClass, property, propertyClass);
    }

    /**
     * 根据条件查找某个属性
     *
     * @param <T>           类型
     * @param criteria      查询
     * @param documentClass 类
     * @param property      属性
     * @param propertyClass 属性类
     * @return List 列表
     */
    public <T, R> List<T> findPropertiesByQuery(Criteria criteria, Class<?> documentClass, SerializableFunction<T, R> property, Class<T> propertyClass) {
        return (List<T>) findPropertiesByQuery(new Query(criteria), documentClass, MongoUtils.getFieldName(property), propertyClass);
    }

    /**
     * @param criteriaWrapper
     * @param documentClass
     * @param property
     * @param propertyClass
     * @description: 根据条件查找某个属性
     * @return: java.util.List<T>
     * @author: gankench@gmail.com
     * @time: 4/6/21 3:28 PM
     */
    public <T, R> List<T> findPropertiesByQuery(CriteriaWrapper criteriaWrapper, Class<?> documentClass, SerializableFunction<T, R> property, Class<T> propertyClass) {
        return (List<T>) findPropertiesByQuery(new Query(criteriaWrapper.build()), documentClass, MongoUtils.getFieldName(property), propertyClass);
    }

    /**
     * @param criteriaWrapper
     * @param documentClass
     * @param property
     * @param propertyClass
     * @description: 根据条件查找某个属性
     * @return: java.util.List<T>
     * @author: gankench@gmail.com
     * @time: 4/6/21 3:28 PM
     */
    public <T> List<T> findPropertiesByQuery(CriteriaWrapper criteriaWrapper, Class<?> documentClass, String property, Class<T> propertyClass) {
        return (List<T>) findPropertiesByQuery(new Query(criteriaWrapper.build()), documentClass, property, propertyClass);
    }

    /**
     * @param criteria
     * @param documentClass
     * @param property
     * @description: 根据条件查找某个属性
     * @return: java.util.List<java.lang.String>
     * @author: gankench@gmail.com
     * @time: 4/6/21 3:29 PM
     */
    public List<String> findPropertiesByQuery(Criteria criteria, Class<?> documentClass, String property) {
        return (List<String>) findPropertiesByQuery(new Query(criteria), documentClass, property, String.class);
    }

    /**
     * 根据条件查找某个属性
     *
     * @param <T>           类型
     * @param criteria      查询
     * @param documentClass 类
     * @param property      属性
     * @return List 列表
     */
    public <T, R> List<String> findPropertiesByQuery(Criteria criteria, Class<?> documentClass, SerializableFunction<T, R> property) {
        return (List<String>) findPropertiesByQuery(new Query(criteria), documentClass, MongoUtils.getFieldName(property), String.class);
    }

    /**
     * @param criteriaWrapper
     * @param documentClass
     * @param property
     * @description: 根据条件查找某个属性
     * @return: java.util.List<java.lang.String>
     * @author: gankench@gmail.com
     * @time: 4/6/21 3:29 PM
     */
    public List<String> findPropertiesByQuery(CriteriaWrapper criteriaWrapper, Class<?> documentClass, String property) {
        return (List<String>) findPropertiesByQuery(new Query(criteriaWrapper.build()), documentClass, property, String.class);
    }


    /**
     * @param criteriaWrapper
     * @param documentClass
     * @param property
     * @description: 根据条件查找某个属性
     * @return: java.util.List<java.lang.String>
     * @author: gankench@gmail.com
     * @time: 4/6/21 3:29 PM
     */
    public <T, R> List<String> findPropertiesByQuery(CriteriaWrapper criteriaWrapper, Class<?> documentClass, SerializableFunction<T, R> property) {
        return (List<String>) findPropertiesByQuery(new Query(criteriaWrapper.build()), documentClass, MongoUtils.getFieldName(property), String.class);
    }

    /**
     * @param ids
     * @param documentClass
     * @param property
     * @description: 根据条件查找某个属性
     * @return: java.util.List<java.lang.String>
     * @author: gankench@gmail.com
     * @time: 4/6/21 3:29 PM
     */
    public List<String> findPropertiesByIds(Collection<String> ids, Class<?> documentClass, String property) {
        return findPropertiesByQuery(Criteria.where("id").in(ids), documentClass, property, String.class);
    }

    /**
     * 根据条件查找id
     *
     * @param criteria 查询
     * @param clazz    类
     * @return List 列表
     */
    public List<String> findIdsByQuery(Criteria criteria, Class<?> clazz) {
        return baseMongoDAO.findIdsByQuery(new Query(criteria), clazz);
    }

    /**
     * 根据条件查找id
     *
     * @param criteriaWrapper 查询
     * @param clazz           类
     * @return List 列表
     */
    public List<String> findIdsByQuery(CriteriaWrapper criteriaWrapper, Class<?> clazz) {
        return baseMongoDAO.findIdsByQuery(new Query(criteriaWrapper.build()), clazz);
    }

    /**
     * 根据条件查找id
     *
     * @param criteria 查询
     * @param clazz    类
     * @return List 列表
     */
    public List<String> findIdsByQuery(Criteria criteria, Sort sort, Class<?> clazz) {
        return baseMongoDAO.findIdsByQuery(new Query(criteria).with(sort), clazz);
    }

    /**
     * 根据条件查找id
     *
     * @param criteria 查询
     * @param clazz    类
     * @return List 列表
     */
    public List<String> findIdsByQuery(Criteria criteria, SortBuilder sortBuilder, Class<?> clazz) {
        return baseMongoDAO.findIdsByQuery(new Query(criteria).with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据条件查找id
     *
     * @param criteriaWrapper 查询
     * @param clazz           类
     * @return List 列表
     */
    public List<String> findIdsByQuery(CriteriaWrapper criteriaWrapper, Sort sort, Class<?> clazz) {
        return baseMongoDAO.findIdsByQuery(new Query(criteriaWrapper.build()).with(sort), clazz);
    }

    /**
     * 根据条件查找id
     *
     * @param criteriaWrapper 查询
     * @param clazz           类
     * @return List 列表
     */
    public List<String> findIdsByQuery(CriteriaWrapper criteriaWrapper, SortBuilder sortBuilder, Class<?> clazz) {
        return baseMongoDAO.findIdsByQuery(new Query(criteriaWrapper.build()).with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据id集合查找
     *
     * @param ids   id集合
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findListByIds(Collection<String> ids, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(new Query(Criteria.where("id").in(ids)), clazz);
    }

    /**
     * 根据id集合查找
     *
     * @param ids   id集合
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findListByIds(Collection<String> ids, SortBuilder sortBuilder, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(new Query(Criteria.where("id").in(ids)).with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据id集合查找
     *
     * @param ids   id集合
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findListByIds(Collection<String> ids, Sort sort, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(new Query(Criteria.where("id").in(ids)).with(sort), clazz);
    }

    /**
     * 根据id集合查找
     *
     * @param ids   id集合
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findListByIds(String[] ids, SortBuilder sortBuilder, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(new Query(Criteria.where("id").in(ids)).with(sortBuilder.toSort()), clazz);
    }

    /**
     * 根据id集合查找
     *
     * @param ids   id集合
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findListByIds(String[] ids, Sort sort, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(new Query(Criteria.where("id").in(ids)).with(sort), clazz);
    }

    /**
     * 根据id集合查找
     *
     * @param ids   id集合
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findListByIds(String[] ids, Class<T> clazz) {
        return baseMongoDAO.findListByQuery(new Query(Criteria.where("id").in(ids)), clazz);
    }

    /**
     * 查询全部
     *
     * @param <T>   类型
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findAll(Class<T> clazz) {
        try {
            return baseMongoDAO.findListByQuery(Wraps.buildBaseQuery(clazz.newInstance()), clazz);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return Lists.newArrayList();
    }

    /**
     * 查询全部
     *
     * @param <T>   类型
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findAll(Sort sort, Class<T> clazz) {
        return findListByQuery(new Criteria(), sort, clazz);
    }

    /**
     * 查询全部
     *
     * @param <T>   类型
     * @param clazz 类
     * @return List 列表
     */
    public <T> List<T> findAll(SortBuilder sortBuilder, Class<T> clazz) {
        return findListByQuery(new Criteria(), sortBuilder.toSort(), clazz);
    }

    /**
     * 查找全部的id
     *
     * @param clazz 类
     * @return List 列表
     */
    public List<String> findAllIds(Class<?> clazz) {
        return baseMongoDAO.findIdsByQuery(new Query(), clazz);
    }

    /**
     * 查找数量
     *
     * @param criteria 查询
     * @param clazz    类
     * @return Long 数量
     */
    public Long findCountByQuery(Criteria criteria, Class<?> clazz) {
        return baseMongoDAO.findCountByQuery(new Query(criteria), clazz);
    }

    /**
     * 查找数量
     *
     * @param criteriaWrapper 查询
     * @param clazz           类
     * @return Long 数量
     */
    public Long findCountByQuery(CriteriaWrapper criteriaWrapper, Class<?> clazz) {
        return baseMongoDAO.findCountByQuery(new Query(criteriaWrapper.build()), clazz);
    }

    /**
     * 查找全部数量
     *
     * @param clazz 类
     * @return Long 数量
     */
    public Long findAllCount(Class<?> clazz) {
        return baseMongoDAO.findCountByQuery(new Query(), clazz);
    }

    /**
     * 获取list中对象某个属性,组成新的list
     *
     * @param list     列表
     * @param clazz    类
     * @param property 属性
     * @return List<T> 列表
     */
    private <T> List<T> extractProperty(List<?> list, String property, Class<?> clazz) {
        Set<T> rs = new HashSet<T>();
        for (Object object : list) {
            Object value = MongoUtils.getFieldValue(object, property);
            if (value != null) {
                if (value.getClass().equals(clazz)) {
                    rs.add((T) value);
                } else {
                    if (value.getClass().toString().equalsIgnoreCase("class java.util.ArrayList")) {
                        List<T> vls = (List<T>) value;
                        rs.addAll(vls);
                    }
                }


            }
        }

        return new ArrayList<T>(rs);
    }

    public <T> T findById(String id, Class<T> clazz) {
        if (StrUtil.isEmpty(id)) {
            return null;
        }
        return (T) baseMongoDAO.findById(id, clazz);
    }

    public void updateAllColumnById(Object object) {
        baseMongoDAO.updateAllColumnById(object);
    }

    private Query buildPageQuery(Query query, Page<?> page) {
        //如果没有条件 则所有全部
        query = query == null ? new Query(Criteria.where("_id").exists(true)) : query;
        // 查询page
        query.skip((page.getPageNum() - 1) * page.getPageSize());// 从那条记录开始
        query.limit(page.getPageSize());// 取多少条记录

        if (!query.isSorted()) {
            query.with(Sort.by(Sort.Direction.DESC, "id"));
        }
        return query;
    }

    @Override
    public List<FlowableForm> list(Page page, FlowableForm flowableForm) {
        return findListByQuery(Wraps.buildBasePageQuery(flowableForm, page), FlowableForm.class);
    }
}
